use clap::*;
use console::style;
use gd_docgen::GDScript;
use indicatif::{ProgressBar, ProgressStyle};
use std::{ffi::OsStr, fs, path::PathBuf};
use walkdir::WalkDir;

fn main() {
    let matches = App::new("gd-docgen")
        .version("0.1.3")
        .author("Hapenia Lans hapenia@sina.com")
        .about("A simple tool to generate markdown api reference from gdscript")
        .args(&[
            Arg::from_usage("<INPUT_DIR>       'sets the input dir to use.'"),
            Arg::from_usage("<TO_DIR>          'sets the output dir to place the api reference.'"),
        ])
        .get_matches();
    if let (Some(input_dir), Some(to_dir)) =
        (matches.value_of("INPUT_DIR"), matches.value_of("TO_DIR"))
    {
        if let Err(_) = fs::remove_dir(to_dir) {}
        if let Err(e) = fs::create_dir(to_dir) {
            eprintln!("{}", e)
        }
        let mut script_paths: Vec<PathBuf> = vec![];
        eprintln!("{}", style("Collecting...").bold().green());
        for entry in WalkDir::new(input_dir).into_iter().filter_map(|e| e.ok()) {
            if entry.path().is_file() {
                if Some(OsStr::new("gd")) == entry.path().extension() {
                    script_paths.push(entry.path().to_path_buf())
                }
            }
        }
        let bar = ProgressBar::new(script_paths.len() as u64);
        bar.set_style(
            ProgressStyle::default_bar()
                .template("{spinner} [{pos}/{len}] {msg} [{bar:40.cyan/blue}]  ")
                .progress_chars("##>-"),
        );
        for i in 0..script_paths.len() {
            let file_name = script_paths[i].file_name().unwrap().to_str().unwrap();
            bar.set_message(format!("item: {}", file_name));
            let gds = GDScript::read_from_file(&script_paths[i]);
            match gds {
                Ok(x) => {
                    if let Err(y) = x.write_to_file(to_dir) {
                        bar.abandon();
                        eprintln!("[{}] {}", file_name, style(y).red());
                        return;
                    }
                },
                Err(x) => {
                    bar.abandon();
                    eprintln!("[{}] {}", file_name, style(x).red());
                    return;
                }
            }
            bar.inc(1);
        }
        bar.finish();
        eprintln!("{}", style("Done!!!").green().bold())
    }
}
